package org.jadelyre.core;

import org.jadelyre.core.codec.Codec;
import org.jadelyre.core.exception.JadelyreException;
import org.jadelyre.core.task.EntryQueue;
import org.jadelyre.core.worker.Worker;
import org.jadelyre.core.worker.WorkerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.channels.AsynchronousChannelGroup;

public abstract class AbstractJadeLyre implements JadeLyre {

    private static final Logger logger = LoggerFactory.getLogger(AbstractJadeLyre.class);

    protected final Handler handler;
    protected final WorkerFactory workerFactory;
    //    protected final CloseTask closeTask;
    protected final Worker<Channel> closeWorker;
    protected final Codec codec;
    protected final AsynchronousChannelGroup asynchronousChannelGroup;
    protected volatile boolean started;

    protected boolean acceptHeartbeat;
    protected Heartbeat heartbeat;//不为空则进行心跳检测

    public AbstractJadeLyre(Handler handler, Codec codec) throws JadelyreException {
        this.handler = handler;
        this.codec = codec;
        workerFactory = initWorker();
        asynchronousChannelGroup = createAsynchronousChannelGroup();
//        closeTask = new CloseTask(this);
        closeWorker = workerFactory.getCloseWorker(new EntryQueue<Channel>());
    }

    public Heartbeat getHeartbeat() {
        return heartbeat;
    }

    public void setHeartbeat(Heartbeat heartbeat) {
        this.heartbeat = heartbeat;
    }

    @Override
    public Handler getHandler() {
        return handler;
    }

    @Override
//    public CloseTask getCloseTask() {
//        return closeTask;
//    }
    public Worker<Channel> getCloseWorker() {
        return closeWorker;
    }

    @Override
    public WorkerFactory getWorkerFactory() {
        return workerFactory;
    }

    @Override
    public Codec getCodec() {
        return codec;
    }

    @Override
    public boolean isStarted() {
        return started;
    }

    protected abstract AsynchronousChannelGroup createAsynchronousChannelGroup() throws JadelyreException;

    protected abstract WorkerFactory initWorker();

    protected abstract void stop() throws JadelyreException;


    public void setStarted(boolean started) {
        this.started = started;
    }

    protected void addShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            if (logger.isInfoEnabled()) {
                logger.info("Run shutdown hook now.");
            }
            stop();
        }, "AbstractJadeLyreShutdownHook"));
    }
}
